package com.quectel.pay.module.order.service.impl;

import com.quectel.constant.global.SystemConstants;
import com.quectel.pay.module.merchant.dto.PayChannelDto;
import com.quectel.pay.module.merchant.service.PayChannelService;
import com.quectel.pay.module.order.dto.PayOrderDto;
import com.quectel.pay.module.order.dto.PayOrderRefundDto;
import com.quectel.pay.module.order.dto.request.InitOrderParams;
import com.quectel.pay.module.order.dto.response.NotifyCheckResult;
import com.quectel.pay.module.order.dto.response.OrderCreatedResponseDto;
import com.quectel.pay.module.order.dto.response.SendRefundResp;
import com.quectel.pay.module.order.service.OrderAliJSAPIPayService;
import com.quectel.pay.module.order.service.OrderWechatJSAPIPayService;
import com.quectel.pay.module.order.service.PayOrderService;
import com.quectel.pay.util.PayInstanceUtils;
import com.quectel.sdk.pay.wxv2.wxsdk.WXPay;
import com.quectel.sdk.pay.wxv2.wxsdk.WXPayConfig;
import com.quectel.sdk.pay.wxv2.wxsdk.WXPayConstants;
import com.quectel.sdk.pay.wxv2.wxsdk.WXPayUtil;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.MapWrapper;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.*;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信JSAPI支付
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2023-04-13 14:04:00
 */
@DubboService
public class OrderWechatJSAPIPayServiceImpl implements OrderWechatJSAPIPayService {
    private static final Logger LOGGER = LoggerFactory.getLogger(OrderWechatJSAPIPayServiceImpl.class);

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private PayChannelService payChannelService;
    @Autowired
    private OrderAliJSAPIPayService orderAliJSAPIPayService;

    @Override
    public OrderCreatedResponseDto createOrder(InitOrderParams initOrderParams) {
        LOGGER.info("Wechat JSAPI-Pay create order params are: {}", JacksonUtils.toJsonString(initOrderParams));

        //初始化订单
        initOrderParams.setPayType(SystemConstants.PayType.WX.getType());

        PayOrderDto orderDto = payOrderService.initOrderInfo(initOrderParams);
        orderDto.setTerminalType(SystemConstants.TerminalType.JSAPI.getType());

        PayChannelDto payChannelDto = payChannelService.selectById(initOrderParams.getPayChannelId());
        PayChannelDto.WeChatJSAPIChannelConfig channelConfig =
                JacksonUtils.parse(payChannelDto.getPayConfig(), PayChannelDto.WeChatJSAPIChannelConfig.class);

        if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V3.equals(channelConfig.getVersion())) {
            // v3
            RSAAutoCertificateConfig config = PayInstanceUtils.getWxJSAPIV3Instance(initOrderParams.getPayChannelId());
            JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
            PrepayRequest prepayRequest = new PrepayRequest();
            prepayRequest.setAppid(channelConfig.getAppId());
            prepayRequest.setMchid(channelConfig.getMchId());
            prepayRequest.setDescription(initOrderParams.getProductName());
            prepayRequest.setOutTradeNo(initOrderParams.getOutTradeNo());
            if (initOrderParams.getTtl() != null && initOrderParams.getTtl() > 0) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+08:00");
                prepayRequest.setTimeExpire(sdf.format(new Date(orderDto.getCreateTime().getTime() + initOrderParams.getTtl())));
            }
            prepayRequest.setNotifyUrl(initOrderParams.getNotifyUrl());

            Amount amount = new Amount();
            amount.setTotal(initOrderParams.getSpecialPrice().multiply(new BigDecimal("100")).intValue());
            amount.setCurrency("CNY");
            prepayRequest.setAmount(amount);

            Payer payer = new Payer();
            payer.setOpenid(initOrderParams.getOpenId());
            prepayRequest.setPayer(payer);

            PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(prepayRequest);
            LOGGER.info("Wechat JSAPI-Pay v3 create order response params are: {}", response.toString());
            if (!response.getPackageVal().equals("prepay_id=null")) {
                Map<String, String> result = new HashMap<>();
                result.put("appId", response.getAppId());
                result.put("timeStamp", response.getTimeStamp());
                result.put("nonceStr", response.getNonceStr());
                result.put("package", response.getPackageVal());
                result.put("signType", response.getSignType());
                result.put("paySign", response.getPaySign());

                OrderCreatedResponseDto orderCreatedResponseDto = new OrderCreatedResponseDto();
                orderCreatedResponseDto.setSuccess(true);
                orderCreatedResponseDto.setOutTradeNo(orderDto.getOutTradeNo());
                orderCreatedResponseDto.setResp(result);
                orderCreatedResponseDto.setVersion(PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V3);
                orderDto.setRedoValue(JacksonUtils.toJsonString(orderCreatedResponseDto));
                payOrderService.save(orderDto);
                LOGGER.info("Wechat JSAPI-Pay v3 create order final params are: {}", JacksonUtils.toJsonString(orderCreatedResponseDto));
                return orderCreatedResponseDto;
            }
        } else if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V2.equals(channelConfig.getVersion())) {
            // v2
            try {
                WXPayConfig wxPayConfig = PayInstanceUtils.getWxJSAPIV2Instance(initOrderParams.getPayChannelId());
                //md5签名
                WXPay wxPay = new WXPay(wxPayConfig, null, true, true);

                Map<String, String> params = new HashMap<>();
                params.put("out_trade_no", orderDto.getOutTradeNo());
                params.put("total_fee", orderDto.getSpecialPrice().multiply(new BigDecimal("100")).intValue() + "");
                params.put("body", orderDto.getProductName());
                params.put("spbill_create_ip", orderDto.getIpAddress());
                params.put("notify_url", orderDto.getNotifyUrl());
                params.put("trade_type", "JSAPI");
                params.put("openid", initOrderParams.getOpenId());
                if (initOrderParams.getTtl() != null && initOrderParams.getTtl() > 0) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//                params.put("time_start", sdf.format(orderDto.getCreateTime()));
                    params.put("time_expire", sdf.format(new Date(orderDto.getCreateTime().getTime() + initOrderParams.getTtl())));
                }

                Map<String, String> requestData = wxPay.fillRequestData(params);

                String withoutCert = wxPay.requestWithoutCert(WXPayConstants.UNIFIEDORDER_URL_SUFFIX, requestData, 10000, 10000);
                Map<String, String> responseMap = WXPayUtil.xmlToMap(withoutCert);
                LOGGER.info("Wechat JSAPI-Pay v2 create order response params are: {}", JacksonUtils.toJsonString(responseMap));
                if (responseMap.containsKey("return_code")
                        && WXPayConstants.SUCCESS.equals(responseMap.get("return_code"))) {

                    /*
                     * <xml>
                     *    <return_code><![CDATA[SUCCESS]]></return_code>
                     *    <return_msg><![CDATA[OK]]></return_msg>
                     *    <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
                     *    <mch_id><![CDATA[10000100]]></mch_id>
                     *    <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
                     *    <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
                     *    <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
                     *    <result_code><![CDATA[SUCCESS]]></result_code>
                     *    <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
                     *    <trade_type><![CDATA[JSAPI]]></trade_type>
                     * </xml>
                     */
                    Map<String, String> result = new HashMap<>();
                    result.put("appId", responseMap.get("appid"));
                    result.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
                    result.put("nonceStr", WXPayUtil.generateNonceStr());
                    result.put("package", "prepay_id=" + responseMap.get("prepay_id"));
                    result.put("signType", WXPayConstants.SignType.MD5.name());
                    result.put("paySign", WXPayUtil.generateSignature(result, wxPayConfig.getKey()));

                    OrderCreatedResponseDto orderCreatedResponseDto = new OrderCreatedResponseDto();
                    orderCreatedResponseDto.setSuccess(true);
                    orderCreatedResponseDto.setOutTradeNo(orderDto.getOutTradeNo());
                    orderCreatedResponseDto.setResp(result);
                    orderCreatedResponseDto.setVersion(PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V2);
                    orderDto.setRedoValue(JacksonUtils.toJsonString(orderCreatedResponseDto));

                    payOrderService.save(orderDto);

                    LOGGER.debug("Wechat JSAPI-Pay v2 create order response params are: {}", JacksonUtils.toJsonString(orderCreatedResponseDto));

                    return orderCreatedResponseDto;
                }
            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v2 create order failed", e);
            }

        }
        return null;
    }

    @Override
    public SendRefundResp sendRefundRequest(Long payChannelId, PayOrderRefundDto refundReq) {
        PayChannelDto payChannelDto = payChannelService.selectById(payChannelId);
        PayChannelDto.WeChatJSAPIChannelConfig channelConfig =
                JacksonUtils.parse(payChannelDto.getPayConfig(), PayChannelDto.WeChatJSAPIChannelConfig.class);

        if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V3.equals(channelConfig.getVersion())) {
            RSAAutoCertificateConfig config = PayInstanceUtils.getWxJSAPIV3Instance(payChannelId);
            RefundService service = new RefundService.Builder().config(config).build();
            CreateRequest createRequest = new CreateRequest();
            createRequest.setOutTradeNo(refundReq.getOutTradeNo());
            createRequest.setOutRefundNo(refundReq.getOutRefundNo());
            createRequest.setNotifyUrl(refundReq.getRefundNotifyUrl());
            AmountReq amountReq = new AmountReq();
            amountReq.setCurrency("CNY");
            amountReq.setTotal(refundReq.getTotalAmount().multiply(new BigDecimal("100")).longValue());
            amountReq.setRefund(refundReq.getRefundAmount().multiply(new BigDecimal("100")).longValue());
            createRequest.setAmount(amountReq);
            Refund refund = service.create(createRequest);
            LOGGER.info("Wechat JSAPI-Pay v3 refund response data：{}", refund.toString());
            if (Status.SUCCESS.equals(refund.getStatus()) || Status.PROCESSING.equals(refund.getStatus())) {
                LOGGER.info("Wechat JSAPI-Pay v3 refund success, the outTradeNo is: {} outRefundNo is: {} ", refundReq.getOutTradeNo(), refundReq.getOutRefundNo());
                return SendRefundResp
                        .builder()
                        .sendSuccess(true)
                        .refundWithSynchronization(false)
                        .build();
            }
            return SendRefundResp
                    .builder()
                    .sendSuccess(false)
                    .refundWithSynchronization(false)
                    .failedReason("未知原因")
                    .build();

        } else if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V2.equals(channelConfig.getVersion())) {
            try {

                //md5签名
                WXPay wxPay = new WXPay(PayInstanceUtils.getWxJSAPIV2Instance(payChannelId), null, true, true);

                Map<String, String> refundQuery = new HashMap<>();
                refundQuery.put("out_refund_no", refundReq.getOutRefundNo());
                wxPay.fillRequestData(refundQuery);
                String refundQueryResp = wxPay.requestWithoutCert(WXPayConstants.REFUNDQUERY_URL_SUFFIX, refundQuery, 10000, 10000);
                Map<String, String> refundQueryRespMap = WXPayUtil.xmlToMap(refundQueryResp);
                if (WXPayConstants.SUCCESS.equals(refundQueryRespMap.get("return_code"))
                        && WXPayConstants.SUCCESS.equals(refundQueryRespMap.get("result_code"))) {
                    for (Map.Entry<String, String> entry : refundQueryRespMap.entrySet()) {
                        if (entry.getKey().startsWith("refund_status_") && WXPayConstants.SUCCESS.equalsIgnoreCase(entry.getValue())) {
                            return SendRefundResp
                                    .builder()
                                    .sendSuccess(true)
                                    .refundWithSynchronization(true)
                                    .refundSuccessTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(refundQueryRespMap.get("refund_success_time_"
                                            + entry.getKey().substring("refund_status_".length()))))
                                    .build();
                        }
                    }
                }


                Map<String, String> params = new HashMap<>();
                params.put("out_trade_no", refundReq.getOutTradeNo());
                params.put("out_refund_no", refundReq.getOutRefundNo());
                params.put("total_fee", refundReq.getTotalAmount().multiply(new BigDecimal("100")).intValue() + "");
                params.put("refund_fee", refundReq.getRefundAmount().multiply(new BigDecimal("100")).intValue() + "");
                params.put("notify_url", refundReq.getRefundNotifyUrl());
                //默认未结算退款
                params.put("refund_account", "REFUND_SOURCE_UNSETTLED_FUNDS");

                Map<String, String> requestData = wxPay.fillRequestData(params);
                String withCert = wxPay.requestWithCert(WXPayConstants.REFUND_URL_SUFFIX, requestData, 10000, 10000);
                Map<String, String> responseMap = WXPayUtil.xmlToMap(withCert);

                LOGGER.info("Wechat JSAPI-Pay v2 refund response data：{}", JacksonUtils.toJsonString(responseMap));

                if (WXPayConstants.SUCCESS.equals(responseMap.get("return_code"))
                        && WXPayConstants.SUCCESS.equals(responseMap.get("result_code"))) {
                    //退款发起成功
                    LOGGER.info("Wechat JSAPI-Pay v2 refund success, the outTradeNo is: {} outRefundNo is: {} ", refundReq.getOutTradeNo(), refundReq.getOutRefundNo());
                    return SendRefundResp.builder().sendSuccess(true).build();
                }
                if (WXPayConstants.SUCCESS.equals(responseMap.get("return_code"))
                        && "FAIL".equals(responseMap.get("result_code"))
                        && "NOTENOUGH".equals(responseMap.get("err_code"))
                ) {
                    //用另一种方式退钱
                    //交易未结算资金不足，请使用可用余额退款  现在就用可用余额退款
                    params.put("refund_account", "REFUND_SOURCE_RECHARGE_FUNDS");

                    requestData = wxPay.fillRequestData(params);
                    withCert = wxPay.requestWithCert(WXPayConstants.REFUND_URL_SUFFIX, requestData, 10000, 10000);
                    responseMap = WXPayUtil.xmlToMap(withCert);

                    if (WXPayConstants.SUCCESS.equals(responseMap.get("return_code"))
                            && WXPayConstants.SUCCESS.equals(responseMap.get("result_code"))) {
                        //退款发起成功
                        LOGGER.info("Wechat JSAPI-Pay v2 refund success used balance of account , the outTradeNo is: {} outRefundNo is: {} ", refundReq.getOutTradeNo(), refundReq.getOutRefundNo());
                        return SendRefundResp
                                .builder()
                                .sendSuccess(true)
                                .refundWithSynchronization(false)
                                .build();
                    }
                }
                LOGGER.info("Wechat JSAPI-Pay v2 refund failed, the outTradeNo is: {} error msg: {}", refundReq.getOutTradeNo(), JacksonUtils.toJsonString(responseMap));
                return SendRefundResp
                        .builder()
                        .sendSuccess(false)
                        .refundWithSynchronization(false)
                        .failedReason(responseMap.get("return_msg"))
                        .build();
            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v2 send refund request failed", e);
            }
        }
        return SendRefundResp
                .builder()
                .sendSuccess(false)
                .refundWithSynchronization(false)
                .failedReason("未知原因")
                .build();

    }

    @Override
    public NotifyCheckResult payNotifyCheck(Long payChannelId, Map<String, String> allHeaders, String recStr) {

        LOGGER.info("Wechat JSAPI-Pay pay notify headers are: {}", JacksonUtils.toJsonString(allHeaders));
        LOGGER.info("Wechat JSAPI-Pay pay notify params are: {}", recStr);

        PayChannelDto payChannelDto = payChannelService.selectById(payChannelId);
        PayChannelDto.WeChatJSAPIChannelConfig channelConfig =
                JacksonUtils.parse(payChannelDto.getPayConfig(), PayChannelDto.WeChatJSAPIChannelConfig.class);

        if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V3.equals(channelConfig.getVersion())) {

            NotifyCheckResult notifyCheckResult = new NotifyCheckResult();
            try {
                RSAAutoCertificateConfig config = PayInstanceUtils.getWxJSAPIV3Instance(payChannelId);
                RequestParam requestParam = new RequestParam.Builder()
                        .serialNumber(channelConfig.getMerchantSerialNumber())
                        .nonce(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Nonce"))
                        .signature(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Signature"))
                        .timestamp(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Timestamp"))
                        .body(recStr)
                        .build();

                NotificationParser notificationParser = new NotificationParser(config);
                Transaction transaction = notificationParser.parse(requestParam, Transaction.class);
                LOGGER.info("Wechat JSAPI-Pay v3 pay notify after parse params are: {}", transaction.toString());
                if (transaction != null && transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) {
                    //支付成功
                    notifyCheckResult.setCheckSuccess(true);
                    notifyCheckResult.setOutTradeNo(transaction.getOutTradeNo());
                    notifyCheckResult.setTradeNo(transaction.getTransactionId());
                    notifyCheckResult.setTradeStatusType(Byte.valueOf("1"));
                    notifyCheckResult.setPaySuccess(true);
                    notifyCheckResult.setPaySuccessTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+08:00").parse(transaction.getSuccessTime()));
                    return notifyCheckResult;
                }
            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v3 pay notify params check error", e);
            }
            return notifyCheckResult;

        } else if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V2.equals(channelConfig.getVersion())) {
            NotifyCheckResult notifyCheckResult = new NotifyCheckResult();
            try {
                Map<String, String> xmlToMap = WXPayUtil.xmlToMap(recStr);
                boolean flag = WXPayUtil.isSignatureValid(xmlToMap, PayInstanceUtils.getWxJSAPIV2Instance(payChannelId).getKey());
                if (flag) {
                    notifyCheckResult.setCheckSuccess(true);
                    notifyCheckResult.setOutTradeNo(xmlToMap.get("out_trade_no"));
                    notifyCheckResult.setTradeNo(xmlToMap.get("transaction_id"));

                    notifyCheckResult.setTradeStatusType(Byte.valueOf("1"));
                    if (WXPayConstants.SUCCESS.equals(xmlToMap.get("return_code")) && WXPayConstants.SUCCESS.equals(xmlToMap.get("result_code"))) {
                        notifyCheckResult.setPaySuccess(true);
                        notifyCheckResult.setPaySuccessTime(new SimpleDateFormat("yyyyMMddHHmmss").parse(xmlToMap.get("time_end")));
                    }
                    return notifyCheckResult;
                }
            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v2 pay notify params check error", e);
            }
            return notifyCheckResult;
        }
        return null;

    }

    @Override
    public NotifyCheckResult refundNotifyCheck(Long payChannelId, Map<String, String> allHeaders, String recStr) {

        LOGGER.info("Wechat JSAPI-Pay refund notify headers are: {}", JacksonUtils.toJsonString(allHeaders));
        LOGGER.info("Wechat JSAPI-Pay refund notify params are: {}", recStr);

        PayChannelDto payChannelDto = payChannelService.selectById(payChannelId);
        PayChannelDto.WeChatJSAPIChannelConfig channelConfig =
                JacksonUtils.parse(payChannelDto.getPayConfig(), PayChannelDto.WeChatJSAPIChannelConfig.class);
        if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V3.equals(channelConfig.getVersion())) {

            NotifyCheckResult notifyCheckResult = new NotifyCheckResult();
            try {
                RSAAutoCertificateConfig config = PayInstanceUtils.getWxJSAPIV3Instance(payChannelId);
                RequestParam requestParam = new RequestParam.Builder()
                        .serialNumber(channelConfig.getMerchantSerialNumber())
                        .nonce(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Nonce"))
                        .signature(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Signature"))
                        .timestamp(MapWrapper.wrap(allHeaders).getValueByIgnoreStringKeyCase("Wechatpay-Timestamp"))
                        .body(recStr)
                        .build();

                NotificationParser notificationParser = new NotificationParser(config);
                RefundNotification refundNotification = notificationParser.parse(requestParam, RefundNotification.class);
                LOGGER.error("Wechat JSAPI-Pay v3 refund notify after parse params are: {}", refundNotification.toString());
                if (refundNotification != null && Status.SUCCESS.equals(refundNotification.getRefundStatus())) {
                    notifyCheckResult.setCheckSuccess(true);
                    notifyCheckResult.setTradeStatusType(Byte.valueOf("2"));

                    notifyCheckResult.setOutTradeNo(refundNotification.getOutTradeNo());
                    notifyCheckResult.setTradeNo(refundNotification.getTransactionId());
                    notifyCheckResult.setRefundSuccess(true);
                    notifyCheckResult.setOutRefundNo(refundNotification.getOutRefundNo());
                    notifyCheckResult.setRefundSuccessTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+08:00").parse(refundNotification.getSuccessTime()));
                    return notifyCheckResult;
                }
            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v3 refund notify params check error", e);
            }
            return notifyCheckResult;

        } else if (PayChannelDto.WeChatJSAPIChannelConfig.VERSION_V2.equals(channelConfig.getVersion())) {
            NotifyCheckResult notifyCheckResult = new NotifyCheckResult();
            try {
                Map<String, String> xmlToMap = WXPayUtil.xmlToMap(recStr);
                if (WXPayConstants.SUCCESS.equals(xmlToMap.get("return_code"))) {

                    //加密后的参数
                    String encryptData = xmlToMap.get("req_info");
                    String originalData = WXPayUtil.AES256ECBDecrypt(PayInstanceUtils.getWxJSAPIV2Instance(payChannelId).getKey(), encryptData);
                    Map<String, String> data = WXPayUtil.xmlToMap(originalData);

                    notifyCheckResult.setCheckSuccess(true);
                    notifyCheckResult.setTradeStatusType(Byte.valueOf("2"));

                    if (WXPayConstants.SUCCESS.equals(data.get("refund_status"))) {
                        notifyCheckResult.setOutTradeNo(data.get("out_trade_no"));
                        notifyCheckResult.setTradeNo(data.get("transaction_id"));
                        notifyCheckResult.setRefundSuccess(true);
                        notifyCheckResult.setOutRefundNo(data.get("out_refund_no"));
                        notifyCheckResult.setRefundSuccessTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(data.get("success_time")));
                        return notifyCheckResult;
                    }
                }

            } catch (Exception e) {
                LOGGER.error("Wechat JSAPI-Pay v2 refund notify params check error", e);
            }
        }

        return null;
    }
}
